package com.java.tutorials.threads;

import java.util.LinkedList;

/**
 * Created by xuzhike on 2016/1/19.
 * http://www.java2s.com/Code/Java/Threads/Definingathreadforathreadpool.htm
 */
public class ThreadPool {
    private LinkedList tasks = new LinkedList();

    public ThreadPool(int size) {
        for (int i = 0; i < size; i++) {
            Thread thread = new ThreadTask(this);
            thread.setName("--------Thread-"+i);
            thread.start();
        }
    }

    public void run(Runnable task) {
        synchronized (tasks) {
            tasks.addLast(task);
            tasks.notify();
        }
    }

    public Runnable getNext() {
        Runnable returnVal = null;
        synchronized (tasks) {
            while (tasks.isEmpty()) {
                try {
                    tasks.wait();
                } catch (InterruptedException ex) {
                    System.err.println("Interrupted");
                }
            }
            returnVal = (Runnable) tasks.removeFirst();
        }
        return returnVal;
    }

    public static void main(String args[]) {
        final String message[] = { "Java", "Source", "and", "Support" };
        ThreadPool pool = new ThreadPool(message.length/2 );
        for (int i = 0, n = message.length; i < n; i++) {
            final int innerI = i;
            Runnable runner = new Runnable() {
                public void run() {
                    System.out.println("current Thread="+Thread.currentThread().getName());
                    for (int j = 0; j < 25; j++) {
                        System.out.println("j: " + j + ": " + message[innerI]);
//                        try {
//                            Thread.sleep(5000l);
//                        } catch (InterruptedException e) {
//                            e.printStackTrace();
//                        }
                    }
                }
            };
            pool.run(runner);
        }
    }
}
class ThreadTask extends Thread {
    private ThreadPool pool;

    public ThreadTask(ThreadPool thePool) {
        pool = thePool;
    }

    public void run() {
        while (true) {
            // blocks until job
            Runnable job = pool.getNext();
            try {
                System.out.println("job="+job.toString());
                job.run();
            } catch (Exception e) {
                // Ignore exceptions thrown from jobs
                System.err.println("Job exception: " + e);
            }
        }
    }
}
